package com.yolib.sanyi;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.Inflater;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.ItemizedOverlay;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapView;
import com.google.android.maps.MyLocationOverlay;
import com.google.android.maps.OverlayItem;
import com.yolib.sanyi.connection.ConnectionService;
import com.yolib.sanyi.connection.event.NewsEvent;
import com.yolib.sanyi.connection.event.EventHandler;
import com.yolib.sanyi.connection.event.StoresEvent;
import com.yolib.sanyi.object.NewsObject;
import com.yolib.sanyi.object.StoreObject;
import com.yolib.sanyi.tool.YoliBLog;

import android.R.mipmap;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.location.Location;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.Html;
import android.text.Spanned;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;

public class MapReviewActivity extends MapActivity implements OnClickListener{

	ListView mListView;
	NewsAdapter mAdapter;
	ImageView mBack;
	LinearLayout mMapViewGroup;
	MapView mMapView;
	Button mListButton;
	Button mMapButton;
	Button mLocationButton01;
	Button mLocationButton02;

	List<StoreObject> mStoreList = new ArrayList<StoreObject>();
	ArrayList<OverlayItem> mOverlays = new ArrayList<OverlayItem>();
	StoreItemizedOverlay mStoreItemizedOverlay;
	MyLocationOverlay myLocationOverlay;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_mapreview);


		mListButton = (Button) findViewById(R.id.activity_mapreview_button_list);
		mMapButton = (Button) findViewById(R.id.activity_mapreview_button_map);
		mLocationButton01 = (Button) findViewById(R.id.location_button1);
		mLocationButton02 = (Button) findViewById(R.id.location_button2);

		mListButton.setEnabled(false);
		mListButton.setOnClickListener(this);
		mMapButton.setOnClickListener(this);
		mLocationButton01.setOnClickListener(this);
		mLocationButton02.setOnClickListener(this);

		mListView = (ListView) findViewById(R.id.map_listview);
		mBack	  = (ImageView) findViewById(R.id.BackImageView);
		mBack.setOnClickListener(this);
		mMapViewGroup = (LinearLayout) findViewById(R.id.map_map);

		if (YoliBLog.isDebug) {
			mMapView = new MapView(this, "0_hkOYtoM3D7dHCv9L8xxrnrPU-SamG-jGcugNw"); // debug key
		}
		else {
			mMapView = new MapView(this, "0WWnlzuscsvOmo__mDiub3zBuaH-VX4vN2gwcPQ"); // publish key
		}
		myLocationOverlay = new MyLocationOverlay(MapReviewActivity.this, mMapView);
		myLocationOverlay.enableMyLocation();

		mStoreItemizedOverlay = new StoreItemizedOverlay(getResources().getDrawable(R.drawable.location), MapReviewActivity.this);
		//設為三義市的某一個店家
		double lon = 120.7612f*1E6;
		double lat = 24.4059f*1E6;
		final GeoPoint mSanYiGeoPoint = new GeoPoint((int)(lat) ,(int)(lon));

		myLocationOverlay.runOnFirstFix(new Runnable() {
			@Override
			public void run() {
					mMapView.getController().animateTo(mSanYiGeoPoint);
			}
		});
		mMapView.setBuiltInZoomControls(true);
		mMapView.getOverlays().add(myLocationOverlay);
		mMapView.getOverlays().add(mStoreItemizedOverlay);
		mMapView.getController().setZoom(17);
		mMapView.setClickable(true);
		mMapView.setEnabled(true);

		mMapViewGroup.addView(mMapView);

		mAdapter = new NewsAdapter(MapReviewActivity.this);
		StoresEvent mStoresEvent = new StoresEvent(MapReviewActivity.this);
		mStoresEvent.setHandler(mHttpHandler);
		ConnectionService.getInstance().addAction(mStoresEvent);
		mListView.setAdapter(mAdapter);

		}

		class NewsAdapter extends BaseAdapter{

			Context mContext;
			LayoutInflater mInflater;
			public NewsAdapter(Context context) {
				mContext = context;
				mInflater = LayoutInflater.from(context);
			}

			@Override
			public int getCount() {
				YoliBLog.e("size: "+ mStoreList.size());
				return mStoreList.size();
			}

			@Override
			public Object getItem(int position) {
				// TODO Auto-generated method stub
				return null;
			}

			@Override
			public long getItemId(int position) {
				// TODO Auto-generated method stub
				return 0;
			}

			@Override
			public View getView(final int position, View convertView, ViewGroup parent) {
				ViewHolder holder;

				if (convertView == null || convertView instanceof TextView) {
					convertView = mInflater.inflate(R.layout.view_store_item, null);

					holder = new ViewHolder();
					holder.distance = (TextView) convertView.findViewById(R.id.view_store_item_distance);
					holder.name = (TextView) convertView.findViewById(R.id.view_store_item_name);
					convertView.setTag(holder);
				} else {
					holder = (ViewHolder) convertView.getTag();
				}

				String str =  mStoreList.get(position).name;
				Spanned spanned = Html.fromHtml(str);
				//			holder.distance.setText(mStoreList.get(position).pubDate);
				holder.name.setText(spanned);
				//			String mDistance = 
				double distance = MapReviewActivity.this.getDistance(mStoreList.get(position));
				int show_distance = (int) distance;
				if(distance == -1)
				{
					mGPSHandler.sendEmptyMessageDelayed(0, 1000);
					holder.distance.setText("處理中…");
				}
				else if(distance < 1000)
				{
					holder.distance.setText(Integer.toString(show_distance) +"公尺");
				}
				else
				{
					float show_distance_float = (float)((float)(show_distance/100) / 10.f);
					holder.distance.setText(Float.toString(show_distance_float) +"公里");
				}

				convertView.setOnClickListener(new OnClickListener() {

					@Override
					public void onClick(View v) {
						Intent mIntent = new Intent(mContext, DiscoverContentActivity.class);
						mIntent.putExtra("content", mStoreList.get(position).content);
						mIntent.putExtra("title", mStoreList.get(position).name);
						mIntent.putExtra("tel", mStoreList.get(position).phone);
						mIntent.putExtra("url", mStoreList.get(position).url);
						mIntent.putExtra("addX", mStoreList.get(position).addX);
						mIntent.putExtra("addY", mStoreList.get(position).addY);
						startActivity(mIntent);
						overridePendingTransition(R.anim.push_left_in, R.anim.push_left_out);
					}
				});
				return convertView;
			}

		}

		class ViewHolder{
			TextView distance;
			TextView name;
		}

		EventHandler mHttpHandler = new EventHandler()
		{
			public void dispatchMessage(Message msg) {
				if(getClassName(msg).compareTo(StoresEvent.class.getName()) == 0){
					DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

					try {
						DocumentBuilder builder = factory.newDocumentBuilder();
						Document document = builder.parse(new InputSource(new ByteArrayInputStream(((String)msg.obj).getBytes("utf-8"))));
						Element root = document.getDocumentElement();
						NodeList nodes = root.getElementsByTagName("store");
						mStoreItemizedOverlay.delOverlay();
						for(int i = 0; i < nodes.getLength(); i++){
							Element newsElement = (Element)nodes.item(i);
							StoreObject mStoreObject = new StoreObject();
							mStoreObject.setStoreData(newsElement.getChildNodes());

							mStoreList.add(mStoreObject);

							double lon = Float.parseFloat(mStoreObject.addX)*1E6;
							double lat = Float.parseFloat(mStoreObject.addY)*1E6;

							Spanned	mStoreName = Html.fromHtml(mStoreObject.name);

							GeoPoint mSanYiGeoPoint = new GeoPoint((int)lat, (int)lon);
							YoliBLog.e("lon:"+lon+" lat:"+lat);
							OverlayItem item = new OverlayItem(mSanYiGeoPoint, mStoreName.toString(), "");
							mStoreItemizedOverlay.addOverlay(item);
							
						}

					} catch (SAXException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} catch (ParserConfigurationException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}

					mAdapter.notifyDataSetChanged();
				}
			}
		};

		@Override
		protected boolean isRouteDisplayed() {
			// TODO Auto-generated method stub
			return false;
		}

		@Override
		public void onClick(View v) {
			switch(v.getId())
			{
			case R.id.BackImageView:
				finish();
				overridePendingTransition(R.anim.push_right_in, R.anim.push_right_out);	
				break;
			case R.id.activity_mapreview_button_list:
				mListButton.setEnabled(false);
				mMapButton.setEnabled(true);
				mListView.setVisibility(View.VISIBLE);
				mMapViewGroup.setVisibility(View.GONE);
				break;
			case R.id.activity_mapreview_button_map:
				mListButton.setEnabled(true);
				mMapButton.setEnabled(false);
				mListView.setVisibility(View.GONE);
				mMapViewGroup.setVisibility(View.VISIBLE);
				break;
			case R.id.location_button1:
				mGPSHandler.sendEmptyMessage(0);
				myLocationOverlay.runOnFirstFix(new Runnable() {
					@Override
					public void run() {
						if(myLocationOverlay.getMyLocation() != null)
							mMapView.getController().animateTo(myLocationOverlay.getMyLocation());
						else
						{
							mGPSHandler.sendEmptyMessageDelayed(-1, 1000);
						}
					}
				});
				break;
			case R.id.location_button2:
				break;
			}
		}

		public double getDistance(StoreObject mStoreObject) {//(double lat1, double lon1, double lat2, double lon2) {
			double lon = Float.parseFloat(mStoreObject.addX);
			double lat = Float.parseFloat(mStoreObject.addY);

			if(lat != 0 && lon != 0) {
				float[] results = new float[3];  
				if(myLocationOverlay.getMyLocation() == null)
					return -1;
				double mylat = myLocationOverlay.getMyLocation().getLatitudeE6() / 1E6;
				double mylon = myLocationOverlay.getMyLocation().getLongitudeE6() / 1E6;
				Location.distanceBetween(lat, lon, mylat, mylon, results);  
				YoliBLog.d("distance = " + results[0]);  
				return results[0];  
			}
			else {
				return -1;
			}
		}  
		//	
		//	
		Handler mGPSHandler = new Handler() {
			public void dispatchMessage(Message msg) {
				if(msg.what == 0)
				{
					if(myLocationOverlay.getMyLocation() == null)
					{
						mGPSHandler.sendEmptyMessageDelayed(0, 3000);
					}
					else
					{
						mAdapter.notifyDataSetChanged();
					}
				}else{
					if(myLocationOverlay.getMyLocation() == null)
					{
						mGPSHandler.sendEmptyMessageDelayed(0, 1000);
					}
					else
					{
						mAdapter.notifyDataSetChanged();
						mMapView.getController().animateTo(myLocationOverlay.getMyLocation());
					}
				}

			};
		};


		public class StoreItemizedOverlay extends ItemizedOverlay<OverlayItem>
		{
			private ArrayList<OverlayItem> mOverlayItems = new ArrayList<OverlayItem>();
			int show_index = -1;
			
			public StoreItemizedOverlay(Drawable defaultMarker, Context context)
			{
				super(boundCenterBottom(defaultMarker));
			}

			public void addOverlay(OverlayItem overlay)
			{
				mOverlayItems.add(overlay);
				populate();
			}

			public void delOverlay()
			{
				synchronized (mOverlayItems) {
					mOverlayItems.clear();
				}
			}


			@Override
			protected OverlayItem createItem(int i)
			{
				return mOverlayItems.get(i);
			}
			@Override
			public int size()
			{
				return mOverlayItems.size();
			}
			@Override
			protected boolean onTap(final int index)
			{
				YoliBLog.e("KEN onTap:"+index);
				
				mMapView.removeAllViews();
				if(show_index == index)
					return true;
				show_index = index;
				OverlayItem item = mOverlayItems.get(index);
				View mTitleView = View.inflate(MapReviewActivity.this, R.layout.view_map_title, null);
				MapView.LayoutParams geoLP = new MapView.LayoutParams(MapView.LayoutParams.WRAP_CONTENT, 
																	  MapView.LayoutParams.WRAP_CONTENT, 
																	  null,
																	  0,
																	  -100,
																	  MapView.LayoutParams.BOTTOM_CENTER);
				geoLP.point = item.getPoint();
				mMapView.addView(mTitleView, geoLP);
				TextView title = (TextView)	findViewById(R.id.map_Title);
				title.setText(mStoreList.get(index).name);
				
				mTitleView.setOnClickListener(new OnClickListener() {

					@Override
					public void onClick(View v) {
						Intent mIntent = new Intent(MapReviewActivity.this, DiscoverContentActivity.class);
						mIntent.putExtra("content", mStoreList.get(index).content);
						mIntent.putExtra("title", mStoreList.get(index).name);
						mIntent.putExtra("tel", mStoreList.get(index).phone);
						mIntent.putExtra("url", mStoreList.get(index).url);
						mIntent.putExtra("addX", mStoreList.get(index).addX);
						mIntent.putExtra("addY", mStoreList.get(index).addY);
						startActivity(mIntent);
						overridePendingTransition(R.anim.push_left_in, R.anim.push_left_out);
					}
				});
				return true;
			}
			
			

		}


	}
